﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ACOMPORTLib;

namespace SharpLab
{
    /// <summary>
    /// Kalsse für die Kommunikation mit der Seriellen Schnittstelle
    /// </summary>
    public class Comm
    {
        //-------------------------------------------------
        //              Private Deklarationen             
        //-------------------------------------------------
        /// <summary>
        /// Anzahl der COM-Anschlüsse, die in der Liste dargestellt werden sollen.
        /// </summary>
        /// <remarks>
        /// Dieser Vert spiegelt nicht die tatsächlich verfügbare Anzahl der Anschlüsse wieder,
        /// sondern kann willkürlich vom Programmierer gesetzt werden!
        /// </remarks>
        private int _ComDeviceCount = 10;
        /// <summary>
        /// Komponente, die den Zugriff auf die Serielle Schnittstelle regelt
        /// </summary>
        ComPort _myComport = new ComPort();
        /// <summary>
        /// Liste mit den Anschlussnamen
        /// </summary>
        List<string> _DeviceList = new List<string>();

        private Timer readTimer = new Timer();


        //-------------------------------------------------
        //              Öffentliche Deklarationen           
        //-------------------------------------------------
        /// <summary>
        /// Generische Version des Eventhandlers
        /// </summary>
        public event EventHandler<ReadEventArgs> RaiseReadEvent;
        /// <summary>
        /// Virtuelle Ereignisfunktion
        /// </summary>
        /// <param name="e">Ereignisargumente</param>
        public virtual void OnRaiseReadEvent(ReadEventArgs e)
        {
            EventHandler<ReadEventArgs> handler = RaiseReadEvent;

            if (handler != null)
            {
                handler(this, e);
            }
        }
        /// <summary>
        /// Konstruktor
        /// </summary>
        public Comm()
        {
            //Timer initialisieren
            readTimer.Interval = 1000;
            readTimer.Tick += new EventHandler(readTimer_Tick);
            //Anschlussparameter setzen
            _myComport.DataBits = (short)_myComport.asDATABITS_8;
            _myComport.Parity = (short)_myComport.asPARITY_NONE;
            _myComport.StopBits = (short)_myComport.asSTOPBITS_1;
            _myComport.BaudRate = 38400;
            _myComport.ComTimeout = 50;
        }
        /// <summary>
        /// Dieses Event wird ausgelöst, wenn 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void readTimer_Tick(object sender, EventArgs e)
        {
            string mess = _myComport.ReadString();
            if (_myComport.IsOpened == -1)
            {
                if ( mess != "")
                {
                    OnRaiseReadEvent(new ReadEventArgs(mess));   
                }
            }
        }
        /// <summary>
        /// Liste mit den Namen den Serielen Schnittstellen
        /// </summary>
        /// <remarks>
        /// Die Liste enthält nicht die tatsächlich verfügbaren Schnittstellen,
        /// sondern nur eine vom Entwickler vorgegebene Anzahl!
        /// <paramref name="_ComDeviceCount"/>
        /// </remarks>
        public List<string> DeviceList
        {
            get
            {
                for(int i = 1; i <= _ComDeviceCount ; i++)
                {
                    _DeviceList.Add("COM" + i.ToString());
                }

                return _DeviceList;
            }
        }
        /// <summary>
        /// Setzt den aktuellen Schnittstellennamen oder gibt diesen zurück
        /// </summary>
        public string DeviceName
        {
            get
            {
                return _myComport.Device;
            }
            set
            {
                _myComport.Device = value;
            }
        }
        /// <summary>
        /// Sendet einen String an den Comport und wartet dann auf die Antwort
        /// </summary>
        /// <param name="Str">Zu sendender Befehl</param>
        /// <returns>Auf den gesendeten Befehl erhaltene Antwort</returns>
        public void SendMessage(string Str)
        {
            _myComport.WriteString(Str);
        }
        /// <summary>
        /// Öffnet die Schnittstelle zur Kommunikation
        /// </summary>
        public void OpenPort()
        {
            if (_myComport.IsOpened != -1)
            {
                _myComport.Open();
                readTimer.Start();
            }
        }
        /// <summary>
        /// Schnittstelle schließen
        /// </summary>
        public void ClosePort()
        {
            if (_myComport.IsOpened == -1)
            {
                _myComport.Close();
                readTimer.Stop();
            }
        }
    }
    /// <summary>
    /// Argument für das ReadEvent
    /// </summary>
    public class ReadEventArgs : EventArgs
    {
        public ReadEventArgs(string data)
        {
            _incomData = data;
        }

        public string incomData
        {
            get
            {
                return _incomData;
            }
            set
            {
                _incomData = value;
            }
        }

        private string _incomData = null;
    }
}
